From: kmacy@shemp.lab.netapp.com Date: Sat, 12 Mar 2005 22:47:17 +0000 (+0000) Subject: bitkeeper revision 1.1236.27.1 (42337175wSkxS0D7A1TSBWgZsfOczg) X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~17857^2~26^2~8^2 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=cb9bd69ccf22373a5bdc4735de591e30ab72a601;p=xen.git bitkeeper revision 1.1236.27.1 (42337175wSkxS0D7A1TSBWgZsfOczg) Add user-level debug support Signed-off-by: Kip Macy --- diff --git a/.rootkeys b/.rootkeys index 3ae07f2290..6732920706 100644 --- a/.rootkeys +++ b/.rootkeys @@ -574,6 +574,7 @@ 41cc934aO1m6NxEh_8eDr9bJIMoLFA tools/libxc/xc_plan9_build.c 3fbba6dctWRWlFJkYb6hdix2X4WMuw tools/libxc/xc_private.c 3fbba6dcbVrG2hPzEzwdeV_UC8kydQ tools/libxc/xc_private.h +42337174PxyzzPk62raDiYCIsfStDg tools/libxc/xc_ptrace.c 40589968UQFnJeOMn8UIFLbXBuwXjw tools/libxc/xc_rrobin.c 41dde8b0pLfAKMs_L9Uri2hnzHiCRQ tools/libxc/xc_vmx_build.c 40e1b09dMYB4ItGCqcMIzirdMd9I-w tools/libxutil/Makefile diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index fde76498a4..da2feeb756 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -45,6 +45,7 @@ kaf24@plym.cl.cam.ac.uk kaf24@scramble.cl.cam.ac.uk kaf24@striker.cl.cam.ac.uk kaf24@viper.(none) +kmacy@shemp.lab.netapp.com laudney@eclipse.(none) lynx@idefix.cl.cam.ac.uk maf46@burn.cl.cam.ac.uk diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index 598a567e6b..cc33da7046 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -29,6 +29,7 @@ SRCS += xc_linux_save.c SRCS += xc_misc.c SRCS += xc_physdev.c SRCS += xc_private.c +SRCS += xc_ptrace.c SRCS += xc_rrobin.c SRCS += xc_vmx_build.c diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 2a41fa6b58..919800c108 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -459,10 +459,11 @@ int xc_linux_build(int xc_handle, memset( &launch_op, 0, sizeof(launch_op) ); - launch_op.u.builddomain.domain = (domid_t)domid; - launch_op.u.builddomain.ctxt = ctxt; + launch_op.u.setdomaininfo.domain = (domid_t)domid; + launch_op.u.setdomaininfo.exec_domain = 0; + launch_op.u.setdomaininfo.ctxt = ctxt; - launch_op.cmd = DOM0_BUILDDOMAIN; + launch_op.cmd = DOM0_SETDOMAININFO; rc = do_dom0_op(xc_handle, &launch_op); return rc; diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index b4ad94479d..938f219ec7 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -638,9 +638,10 @@ int xc_linux_restore(int xc_handle, XcIOContext *ioctxt) xcio_info(ioctxt, "Domain ready to be built.\n"); - op.cmd = DOM0_BUILDDOMAIN; - op.u.builddomain.domain = (domid_t)dom; - op.u.builddomain.ctxt = &ctxt; + op.cmd = DOM0_SETDOMAININFO; + op.u.setdomaininfo.domain = (domid_t)dom; + op.u.setdomaininfo.exec_domain = 0; + op.u.setdomaininfo.ctxt = &ctxt; rc = do_dom0_op(xc_handle, &op); if ( rc != 0 ) diff --git a/tools/libxc/xc_plan9_build.c b/tools/libxc/xc_plan9_build.c index a7e37c13a5..c6778d44bc 100755 --- a/tools/libxc/xc_plan9_build.c +++ b/tools/libxc/xc_plan9_build.c @@ -533,10 +533,11 @@ xc_plan9_build(int xc_handle, memset(&launch_op, 0, sizeof (launch_op)); - launch_op.u.builddomain.domain = (domid_t) domid; - // launch_op.u.builddomain.num_vifs = 1; - launch_op.u.builddomain.ctxt = ctxt; - launch_op.cmd = DOM0_BUILDDOMAIN; + launch_op.u.setdomaininfo.domain = (domid_t) domid; + launch_op.u.setdomaininfo.exec_domain = 0; + // launch_op.u.setdomaininfo.num_vifs = 1; + launch_op.u.setdomaininfo.ctxt = ctxt; + launch_op.cmd = DOM0_SETDOMAININFO; rc = do_dom0_op(xc_handle, &launch_op); fprintf(stderr, "RC is %d\n", rc); diff --git a/tools/libxc/xc_ptrace.c b/tools/libxc/xc_ptrace.c new file mode 100644 index 0000000000..ea0b9f44c5 --- /dev/null +++ b/tools/libxc/xc_ptrace.c @@ -0,0 +1,341 @@ +#include +#include +#include "xc_private.h" +#include +#include + + +#define BSD_PAGE_MASK (PAGE_SIZE-1) +#define PG_FRAME (~((unsigned long)BSD_PAGE_MASK) +#define PDRSHIFT 22 +#define PSL_T 0x00000100 /* trace enable bit */ + + +/* + * long + * ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data); + */ + +long xc_ptrace(enum __ptrace_request request, + pid_t pid, void *addr, void *data); +int waitdomain(int domain, int *status, int options); + +char * ptrace_names[] = { + "PTRACE_TRACEME", + "PTRACE_PEEKTEXT", + "PTRACE_PEEKDATA", + "PTRACE_PEEKUSER", + "PTRACE_POKETEXT", + "PTRACE_POKEDATA", + "PTRACE_POKEUSER", + "PTRACE_CONT", + "PTRACE_KILL", + "PTRACE_SINGLESTEP", + "PTRACE_INVALID", + "PTRACE_INVALID", + "PTRACE_GETREGS", + "PTRACE_SETREGS", + "PTRACE_GETFPREGS", + "PTRACE_SETFPREGS", + "PTRACE_ATTACH", + "PTRACE_DETACH", + "PTRACE_GETFPXREGS", + "PTRACE_SETFPXREGS", + "PTRACE_INVALID", + "PTRACE_INVALID", + "PTRACE_INVALID", + "PTRACE_INVALID", + "PTRACE_SYSCALL", +}; + +struct gdb_regs { + long ebx; /* 0 */ + long ecx; /* 4 */ + long edx; /* 8 */ + long esi; /* 12 */ + long edi; /* 16 */ + long ebp; /* 20 */ + long eax; /* 24 */ + int xds; /* 28 */ + int xes; /* 32 */ + int xfs; /* 36 */ + int xgs; /* 40 */ + long orig_eax; /* 44 */ + long eip; /* 48 */ + int xcs; /* 52 */ + long eflags; /* 56 */ + long esp; /* 60 */ + int xss; /* 64 */ +}; +#define printval(x) printf("%s = %lx\n", #x, (long)x); +#define SET_PT_REGS(pt, xc) \ +{ \ +pt.ebx = xc.ebx; \ +pt.ecx = xc.ecx; \ +pt.edx = xc.edx; \ +pt.esi = xc.esi; \ +pt.edi = xc.edi; \ +pt.ebp = xc.ebp; \ +pt.eax = xc.eax; \ +pt.eip = xc.eip; \ +pt.xcs = xc.cs; \ +pt.eflags = xc.eflags; \ +pt.esp = xc.esp; \ +pt.xss = xc.ss; \ +pt.xes = xc.es; \ +pt.xds = xc.ds; \ +pt.xfs = xc.fs; \ +pt.xgs = xc.gs; \ +} + +#define SET_XC_REGS(pt, xc) \ +{ \ +xc.ebx = pt->ebx; \ +xc.ecx = pt->ecx; \ +xc.edx = pt->edx; \ +xc.esi = pt->esi; \ +xc.edi = pt->edi; \ +xc.ebp = pt->ebp; \ +xc.eax = pt->eax; \ +xc.eip = pt->eip; \ +xc.cs = pt->xcs; \ +xc.eflags = pt->eflags; \ +xc.esp = pt->esp; \ +xc.ss = pt->xss; \ +xc.es = pt->xes; \ +xc.ds = pt->xds; \ +xc.fs = pt->xfs; \ +xc.gs = pt->xgs; \ +} + + +#define vtopdi(va) ((va) >> PDRSHIFT) +#define vtopti(va) (((va) >> PAGE_SHIFT) & BSD_PAGE_MASK) + +/* XXX application state */ + + +static int xc_handle; +static int regs_valid; +static unsigned long cr3; +static full_execution_context_t ctxt; + +/* --------------------- */ + +static void * +map_domain_va(unsigned long domid, void * guest_va) +{ + unsigned long pde, page; + unsigned long va = (unsigned long)guest_va; + + static unsigned long cr3_phys; + static unsigned long *cr3_virt; + static unsigned long pde_phys; + static unsigned long *pde_virt; + static unsigned long page_phys; + static unsigned long *page_virt; + + if (cr3 != cr3_phys) + { + cr3_phys = cr3; + if (cr3_virt) + munmap(cr3_virt, PAGE_SIZE); + if ((cr3_virt = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, + PROT_READ, + cr3_phys >> PAGE_SHIFT)) == NULL) + goto error_out; + } + pde = cr3_virt[vtopdi(va)]; + if (pde != pde_phys) + { + pde_phys = pde; + if (pde_virt) + munmap(pde_virt, PAGE_SIZE); + if ((pde_virt = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, + PROT_READ, + pde_phys >> PAGE_SHIFT)) == NULL) + goto error_out; + } + page = pde_virt[vtopti(va)]; + if (page != page_phys) + { + page_phys = page; + if (page_virt) + munmap(page_virt, PAGE_SIZE); + if ((page_virt = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, + PROT_READ|PROT_WRITE, + page_phys >> PAGE_SHIFT)) == NULL) + goto error_out; + } + return (void *)(((unsigned long)page_virt) | (va & BSD_PAGE_MASK)); + + error_out: + return 0; +} + +int +waitdomain(int domain, int *status, int options) +{ + dom0_op_t op; + int retval; + full_execution_context_t ctxt; + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 10*1000*1000; + + if (!xc_handle) + if ((xc_handle = xc_interface_open()) < 0) + { + printf("xc_interface_open failed\n"); + return -1; + } + op.cmd = DOM0_GETDOMAININFO; + op.u.getdomaininfo.domain = domain; + op.u.getdomaininfo.exec_domain = 0; + op.u.getdomaininfo.ctxt = &ctxt; + retry: + + retval = do_dom0_op(xc_handle, &op); + if (retval) { + printf("getdomaininfo failed\n"); + goto done; + } + *status = op.u.getdomaininfo.flags; + + if (options & WNOHANG) + goto done; + + + if (!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED)) { + nanosleep(&ts,NULL); + goto retry; + } + done: + return retval; + +} + +long +xc_ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data) +{ + dom0_op_t op; + int status = 0; + xc_domaininfo_t info; + struct gdb_regs pt; + long retval = 0; + long *guest_va; + + op.interface_version = DOM0_INTERFACE_VERSION; + + if (!xc_handle) + if ((xc_handle = xc_interface_open()) < 0) + return -1; +#if 0 + printf("%20s %d, %p, %p \n", ptrace_names[request], pid, addr, data); +#endif + switch (request) { + case PTRACE_PEEKTEXT: + case PTRACE_PEEKDATA: + case PTRACE_POKETEXT: + case PTRACE_POKEDATA: + if ((guest_va = (unsigned long *)map_domain_va(pid, addr)) == NULL) + goto done; + + if (request == PTRACE_PEEKTEXT || request == PTRACE_PEEKDATA) + retval = *guest_va; + else + *guest_va = (unsigned long)data; + break; + case PTRACE_GETREGS: + case PTRACE_GETFPREGS: + case PTRACE_GETFPXREGS: + /* XXX hard-coding UP */ + retval = xc_domain_getfullinfo(xc_handle, pid, 0, &info, &ctxt); + + if (retval) { + printf("getfullinfo failed\n"); + goto done; + } + if (request == PTRACE_GETREGS) { + SET_PT_REGS(pt, ctxt.cpu_ctxt); + memcpy(data, &pt, sizeof(elf_gregset_t)); + } else if (request == PTRACE_GETFPREGS) + memcpy(data, &ctxt.fpu_ctxt, sizeof(elf_fpregset_t)); + else /*if (request == PTRACE_GETFPXREGS)*/ + memcpy(data, &ctxt.fpu_ctxt, sizeof(elf_fpxregset_t)); + cr3 = ctxt.pt_base; + regs_valid = 1; + break; + case PTRACE_SETREGS: + op.cmd = DOM0_SETDOMAININFO; + SET_XC_REGS(((struct gdb_regs *)data), ctxt.cpu_ctxt); + op.u.setdomaininfo.domain = pid; + /* XXX need to understand multiple exec_domains */ + op.u.setdomaininfo.exec_domain = 0; + op.u.setdomaininfo.ctxt = &ctxt; + retval = do_dom0_op(xc_handle, &op); + if (retval) + goto done; + + break; + case PTRACE_ATTACH: + op.cmd = DOM0_GETDOMAININFO; + op.u.getdomaininfo.domain = pid; + op.u.getdomaininfo.exec_domain = 0; + op.u.getdomaininfo.ctxt = &ctxt; + retval = do_dom0_op(xc_handle, &op); + if (retval) { + perror("dom0 op failed"); + goto done; + } + if (op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) { + printf("domain currently paused\n"); + goto done; + } + printf("domain not currently paused\n"); + op.cmd = DOM0_PAUSEDOMAIN; + op.u.pausedomain.domain = pid; + retval = do_dom0_op(xc_handle, &op); + break; + case PTRACE_SINGLESTEP: + ctxt.cpu_ctxt.eflags |= PSL_T; + op.cmd = DOM0_SETDOMAININFO; + op.u.setdomaininfo.domain = pid; + op.u.setdomaininfo.exec_domain = 0; + op.u.setdomaininfo.ctxt = &ctxt; + retval = do_dom0_op(xc_handle, &op); + if (retval) { + perror("dom0 op failed"); + goto done; + } + case PTRACE_CONT: + case PTRACE_DETACH: + regs_valid = 0; + op.cmd = DOM0_UNPAUSEDOMAIN; + op.u.unpausedomain.domain = pid > 0 ? pid : -pid; + retval = do_dom0_op(xc_handle, &op); + break; + case PTRACE_SETFPREGS: + case PTRACE_SETFPXREGS: + case PTRACE_PEEKUSER: + case PTRACE_POKEUSER: + case PTRACE_SYSCALL: + case PTRACE_KILL: +#ifdef DEBUG + printf("unsupported xc_ptrace request %s\n", ptrace_names[request]); +#endif + /* XXX not yet supported */ + status = ENOSYS; + break; + case PTRACE_TRACEME: + printf("PTRACE_TRACEME is an invalid request under Xen\n"); + status = EINVAL; + } + + if (status) { + errno = status; + retval = -1; + } + done: + return retval; +} diff --git a/tools/libxc/xc_vmx_build.c b/tools/libxc/xc_vmx_build.c index 07017291ec..b2b4054523 100644 --- a/tools/libxc/xc_vmx_build.c +++ b/tools/libxc/xc_vmx_build.c @@ -603,10 +603,11 @@ int xc_vmx_build(int xc_handle, memset( &launch_op, 0, sizeof(launch_op) ); - launch_op.u.builddomain.domain = (domid_t)domid; - launch_op.u.builddomain.ctxt = ctxt; + launch_op.u.setdomaininfo.domain = (domid_t)domid; + launch_op.u.setdomaininfo.exec_domain = 0; + launch_op.u.setdomaininfo.ctxt = ctxt; - launch_op.cmd = DOM0_BUILDDOMAIN; + launch_op.cmd = DOM0_SETDOMAININFO; rc = do_dom0_op(xc_handle, &launch_op); return rc; diff --git a/xen/Rules.mk b/xen/Rules.mk index d8de5c3535..e262d690c8 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -1,6 +1,7 @@ verbose ?= n debug ?= n +debugger ?= n perfc ?= n trace ?= n optimize ?= y @@ -54,6 +55,10 @@ else CFLAGS += -DVERBOSE endif +ifeq ($(debugger),y) +CFLAGS += -DXEN_UDB +endif + ifeq ($(crash_debug),y) CFLAGS += -g -DCRASH_DEBUG endif diff --git a/xen/arch/ia64/domain.c b/xen/arch/ia64/domain.c index c5f1533f88..612a2059d0 100644 --- a/xen/arch/ia64/domain.c +++ b/xen/arch/ia64/domain.c @@ -200,7 +200,7 @@ void arch_do_boot_vcpu(struct exec_domain *p) return; } -int arch_final_setup_guest(struct exec_domain *p, full_execution_context_t *c) +int arch_set_info_guest(struct exec_domain *p, full_execution_context_t *c) { dummy(); return 1; diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index cfb60bfcb5..1b48f8822b 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -423,13 +423,23 @@ out: /* This is called by arch_final_setup_guest and do_boot_vcpu */ -int arch_final_setup_guest( +int arch_set_info_guest( struct exec_domain *ed, full_execution_context_t *c) { struct domain *d = ed->domain; unsigned long phys_basetab; int i, rc; + /* + * This is sufficient! If the descriptor DPL differs from CS RPL then we'll + * #GP. If DS, ES, FS, GS are DPL 0 then they'll be cleared automatically. + * If SS RPL or DPL differs from CS RPL then we'll #GP. + */ + if (!(c->flags & ECF_VMX_GUEST)) + if ( ((c->cpu_ctxt.cs & 3) == 0) || + ((c->cpu_ctxt.ss & 3) == 0) ) + return -EINVAL; + clear_bit(EDF_DONEFPUINIT, &ed->ed_flags); if ( c->flags & ECF_I387_VALID ) set_bit(EDF_DONEFPUINIT, &ed->ed_flags); @@ -441,6 +451,11 @@ int arch_final_setup_guest( memcpy(&ed->arch.user_ctxt, &c->cpu_ctxt, sizeof(ed->arch.user_ctxt)); + + memcpy(&ed->arch.i387, + &c->fpu_ctxt, + sizeof(ed->arch.i387)); + /* IOPL privileges are virtualised. */ ed->arch.iopl = (ed->arch.user_ctxt.eflags >> 12) & 3; ed->arch.user_ctxt.eflags &= ~EF_IOPL; @@ -449,19 +464,8 @@ int arch_final_setup_guest( if (!IS_PRIV(d)) ed->arch.user_ctxt.eflags &= 0xffffcfff; - /* - * This is sufficient! If the descriptor DPL differs from CS RPL then we'll - * #GP. If DS, ES, FS, GS are DPL 0 then they'll be cleared automatically. - * If SS RPL or DPL differs from CS RPL then we'll #GP. - */ - if (!(c->flags & ECF_VMX_GUEST)) - if ( ((ed->arch.user_ctxt.cs & 3) == 0) || - ((ed->arch.user_ctxt.ss & 3) == 0) ) - return -EINVAL; - - memcpy(&ed->arch.i387, - &c->fpu_ctxt, - sizeof(ed->arch.i387)); + if (test_bit(EDF_DONEINIT, &ed->ed_flags)) + return 0; memcpy(ed->arch.traps, &c->trap_ctxt, @@ -509,10 +513,14 @@ int arch_final_setup_guest( #endif update_pagetables(ed); + + /* Don't redo final setup */ + set_bit(EDF_DONEINIT, &ed->ed_flags); return 0; } + void new_thread(struct exec_domain *d, unsigned long start_pc, unsigned long start_stack, diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 60a8b74b75..df728da1a7 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -222,8 +222,19 @@ asmlinkage int do_int3(struct xen_regs *regs) DEBUGGER_trap_fatal(TRAP_int3, regs); show_registers(regs); panic("CPU%d FATAL TRAP: vector = 3 (Int3)\n", smp_processor_id()); + } +#ifdef XEN_UDB + else if ( KERNEL_MODE(ed, regs) && ed->domain->id != 0 ) + { + if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) { + while (ed == current) + __enter_scheduler(); + domain_pause_by_systemcontroller(ed->domain); + } + + return 0; } - +#endif /* XEN_UDB */ ti = current->arch.traps + 3; tb->flags = TBF_EXCEPTION; tb->cs = ti->cs; @@ -886,8 +897,8 @@ asmlinkage int math_state_restore(struct xen_regs *regs) asmlinkage int do_debug(struct xen_regs *regs) { unsigned long condition; - struct exec_domain *d = current; - struct trap_bounce *tb = &d->arch.trap_bounce; + struct exec_domain *ed = current; + struct trap_bounce *tb = &ed->arch.trap_bounce; DEBUGGER_trap_entry(TRAP_debug, regs); @@ -895,7 +906,7 @@ asmlinkage int do_debug(struct xen_regs *regs) /* Mask out spurious debug traps due to lazy DR7 setting */ if ( (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) && - (d->arch.debugreg[7] == 0) ) + (ed->arch.debugreg[7] == 0) ) { __asm__("mov %0,%%db7" : : "r" (0UL)); goto out; @@ -912,14 +923,26 @@ asmlinkage int do_debug(struct xen_regs *regs) * breakpoint, which can't happen to us. */ goto out; - } + } +#ifdef XEN_UDB + else if ( KERNEL_MODE(ed, regs) && ed->domain->id != 0 ) + { + regs->eflags &= ~EF_TF; + if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) { + while (ed == current) + __enter_scheduler(); + domain_pause_by_systemcontroller(ed->domain); + } + goto out; + } +#endif /* XEN_UDB */ /* Save debug status register where guest OS can peek at it */ - d->arch.debugreg[6] = condition; + ed->arch.debugreg[6] = condition; tb->flags = TBF_EXCEPTION; - tb->cs = d->arch.traps[1].cs; - tb->eip = d->arch.traps[1].address; + tb->cs = ed->arch.traps[1].cs; + tb->eip = ed->arch.traps[1].address; out: return EXCRET_not_a_fault; diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 2bf6f1aaf6..75547d989c 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -111,13 +111,13 @@ long do_dom0_op(dom0_op_t *u_dom0_op) switch ( op->cmd ) { - case DOM0_BUILDDOMAIN: + case DOM0_SETDOMAININFO: { - struct domain *d = find_domain_by_id(op->u.builddomain.domain); + struct domain *d = find_domain_by_id(op->u.setdomaininfo.domain); ret = -ESRCH; if ( d != NULL ) { - ret = final_setup_guest(d, &op->u.builddomain); + ret = set_info_guest(d, &op->u.setdomaininfo); put_domain(d); } } diff --git a/xen/common/domain.c b/xen/common/domain.c index 50e3b85405..1b1edfe7f6 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -256,31 +256,34 @@ void domain_destruct(struct domain *d) /* - * final_setup_guest is used for final setup and launching of domains other - * than domain 0. ie. the domains that are being built by the userspace dom0 - * domain builder. + * set_info_guest is used for final setup, launching, and state modification + * of domains other than domain 0. ie. the domains that are being built by + * the userspace dom0 domain builder. */ -int final_setup_guest(struct domain *p, dom0_builddomain_t *builddomain) +int set_info_guest(struct domain *p, dom0_setdomaininfo_t *setdomaininfo) { int rc = 0; - full_execution_context_t *c; + full_execution_context_t *c = NULL; + unsigned long vcpu = setdomaininfo->exec_domain; + struct exec_domain *ed; + + if ( (vcpu >= MAX_VIRT_CPUS) || ((ed = p->exec_domain[vcpu]) != NULL) ) + return -EINVAL; + + if (test_bit(DF_CONSTRUCTED, &p->d_flags) && + !test_bit(EDF_CTRLPAUSE, &ed->ed_flags)) + return -EINVAL; if ( (c = xmalloc(full_execution_context_t)) == NULL ) return -ENOMEM; - if ( test_bit(DF_CONSTRUCTED, &p->d_flags) ) - { - rc = -EINVAL; - goto out; - } - - if ( copy_from_user(c, builddomain->ctxt, sizeof(*c)) ) + if ( copy_from_user(c, setdomaininfo->ctxt, sizeof(*c)) ) { rc = -EFAULT; goto out; } - if ( (rc = arch_final_setup_guest(p->exec_domain[0],c)) != 0 ) + if ( (rc = arch_set_info_guest(ed, c)) != 0 ) goto out; set_bit(DF_CONSTRUCTED, &p->d_flags); @@ -331,7 +334,7 @@ long do_boot_vcpu(unsigned long vcpu, full_execution_context_t *ctxt) sched_add_domain(ed); - if ( (rc = arch_final_setup_guest(ed, c)) != 0 ) { + if ( (rc = arch_set_info_guest(ed, c)) != 0 ) { sched_rem_domain(ed); goto out; } diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index 6ba044300f..b60b435941 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -109,16 +109,16 @@ typedef struct { u64 cpu_time; /* 40 */ } PACKED dom0_getdomaininfo_t; /* 48 bytes */ -#define DOM0_BUILDDOMAIN 13 +#define DOM0_SETDOMAININFO 13 typedef struct { /* IN variables. */ - domid_t domain; /* 0 */ - u16 __pad0; /* 2 */ - u32 __pad1; /* 4 */ + domid_t domain; /* 0 */ + u16 exec_domain; /* 2 */ + u32 __pad0; /* 4 */ /* IN/OUT parameters */ - full_execution_context_t *ctxt; /* 8 */ + full_execution_context_t *ctxt; /* 8 */ MEMORY_PADDING; -} PACKED dom0_builddomain_t; /* 16 bytes */ +} PACKED dom0_setdomaininfo_t; /* 16 bytes */ #define DOM0_IOPL 14 typedef struct { @@ -426,7 +426,7 @@ typedef struct { dom0_getmemlist_t getmemlist; dom0_schedctl_t schedctl; dom0_adjustdom_t adjustdom; - dom0_builddomain_t builddomain; + dom0_setdomaininfo_t setdomaininfo; dom0_getdomaininfo_t getdomaininfo; dom0_getpageframeinfo_t getpageframeinfo; dom0_iopl_t iopl; diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h index 8db16e2512..0115f7d0e5 100644 --- a/xen/include/xen/domain.h +++ b/xen/include/xen/domain.h @@ -18,7 +18,7 @@ extern void arch_do_createdomain(struct exec_domain *ed); extern void arch_do_boot_vcpu(struct exec_domain *ed); -extern int arch_final_setup_guest( +extern int arch_set_info_guest( struct exec_domain *d, full_execution_context_t *c); extern void free_perdomain_pt(struct domain *d); diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 68fa4e90d4..9a8746dcfd 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -220,7 +220,7 @@ extern int construct_dom0( unsigned long image_start, unsigned long image_len, unsigned long initrd_start, unsigned long initrd_len, char *cmdline); -extern int final_setup_guest(struct domain *d, dom0_builddomain_t *); +extern int set_info_guest(struct domain *d, dom0_setdomaininfo_t *); struct domain *find_domain_by_id(domid_t dom); struct domain *find_last_domain(void); @@ -317,6 +317,7 @@ extern struct domain *domain_list; #define EDF_RUNNING 12 /* Currently running on a CPU. */ #define EDF_CPUPINNED 13 /* Disables auto-migration. */ #define EDF_MIGRATED 14 /* Domain migrated between CPUs. */ +#define EDF_DONEINIT 15 /* Initialization completed . */ static inline int domain_runnable(struct exec_domain *d) {